<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- 定义对象之间一对多的依赖关系，当一个对象发生改变的时候，所有依赖于它的对象都会得到通知，并且会自动更新消息，观察者模式是属于行为型模式，行为型模式关注的是对象之间的通讯，观察者模式就是观察者和被观察者之间的通讯 -->
    <!-- 与发布订阅模式的区别：
    触发的回调函数方式不同，在观察者模式中依赖的是用户对象（响应式对象）通知之后执行一个更新方法（观察者模式中的方法）（发布订阅模式是通过自定义触发） -->
    <!-- 生活例子
    发布订阅模式：公司给客户发快递，公司和用户是独立的，唯一桥梁就是‘快递站’顺丰韵达。。。。 
    观察者模式：公司给员工发年终奖，由公司的财务部门发放奖金 （不可交给第三者），原因是公司和员工是一个整体-->
    <script>
        // 发布中心
        class Dep {
            constructor() {
                // 记录所有的订阅者（观察者）
                this.subs = []

            }
            // 添加订阅者（观察者）
            addsub(sub) {
                // 将观察者放进subs数组中（记录所有的观察者）
                if (sub) {
                    this.subs.push(sub)
                }
            }
            // 发布通知
            notify() {
                // 发布通知后，所有依赖对象中的观察者需要执行更新方法
                this.subs.forEach(item => {
                    console.log(item);
                    item.updated() //执行观察者中自带的updated方法（通知观察者，当前通知已发布）
                })
            }

        }
        // 订阅者（观察者）
        class Watcher {
            // 更新方法
            updated() {
                // 接收发布通知
                console.log('更新方法');
                // 执行模板函数，更新视图
            }
        }
        // 实例化发布中心
        let dep = new Dep()

        // 实例化多个观察者
        let w1 = new Watcher()
        let w2 = new Watcher()

        // 将观察者添加到subs
        dep.addsub(观察者1)
        dep.addsub(观察者2)

        // 发布通知
        setTimeout(() => {
            dep.notify()
        }, 2000);
    </script>

</body>

</html>